# frozen_string_literal: true

module API
  class VulnerabilityIssueLinks < ::API::Base
    include ::API::Helpers::VulnerabilitiesHooks

    feature_category :vulnerability_management
    urgency :low

    helpers ::API::Helpers::VulnerabilitiesHelpers

    helpers do
      def find_vulnerability!
        Vulnerability.find(params[:id])
      end

      def render_issue_link_response(response)
        if response.success?
          present(response.payload[:record], with: EE::API::Entities::VulnerabilityIssueLink, current_user: current_user)
        else
          render_api_error!(response.message, response.http_status)
        end
      end

      def find_issue_link!
        ::Vulnerabilities::IssueLink.find(params[:issue_link_id])
      end
    end

    params do
      requires :id, type: Integer, desc: 'The ID of a vulnerability'
    end
    resource :vulnerabilities do
      desc 'Get related issues for a vulnerability' do
        success EE::API::Entities::VulnerabilityRelatedIssue
        is_array true
      end
      get ':id/issue_links' do
        vulnerability = find_and_authorize_vulnerability!(:read_security_resource)
        related_issues = vulnerability.related_issues.with_api_entity_associations.with_vulnerability_links
        present Ability.issues_readable_by_user(related_issues, current_user),
          with: EE::API::Entities::VulnerabilityRelatedIssue
      end

      desc 'Relate an issue to a vulnerability' do
        success EE::API::Entities::VulnerabilityIssueLink
      end
      params do
        requires :target_issue_iid, type: Integer, desc: 'The IID of an issue to relate to'
        optional :target_project_id, type: String, desc: 'The ID of the target project'
        optional :link_type, type: String, default: 'related', desc: 'Link type'
      end
      post ':id/issue_links' do
        vulnerability = find_and_authorize_vulnerability!(:admin_vulnerability_issue_link)
        issue = find_project_issue(params[:target_issue_iid], params[:target_project_id].presence || vulnerability.project_id)

        response = ::VulnerabilityIssueLinks::CreateService.new(
          current_user, vulnerability, issue, link_type: params[:link_type]).execute

        render_issue_link_response(response)
      end

      desc 'Delete a link between an issue and a vulnerability' do
        success EE::API::Entities::VulnerabilityIssueLink
      end
      params do
        requires :issue_link_id, type: Integer, desc: 'The ID of a vulnerability-issue-link to delete'
      end
      delete ':id/issue_links/:issue_link_id' do
        find_and_authorize_vulnerability!(:admin_vulnerability_issue_link)
        issue_link = find_issue_link!

        service_response = ::VulnerabilityIssueLinks::DeleteService.new(current_user, issue_link).execute

        render_issue_link_response(service_response)
      end
    end
  end
end
